package gdt.service;

import java.util.List;

import javax.persistence.NoResultException;

import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import gdt.dao.ProjectDAO;
import gdt.entity.Member;
import gdt.entity.Project;
import gdt.service.utils.Validator;


public class ProjectService {

	@Transactional(readOnly=true)
	public Project findById(long id){
		return projectDao.findById(id);
	}
	
	@Transactional(readOnly=true)
	public List<Project> findByUser(String username){
		Member user = memberService.findByUsername(username);
		if(memberService.isAdmin(user))
			return user.getGroup().getProjects();
		else
			return user.getAssignedProjects();
	}
	
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
	public boolean save(Project project, MessageContext messageContext){
		if(validate(project,messageContext)){
			save(project);
			return true;
		}
		else{
			return false;
		}
	}
	
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
	public void save(Project project){
		project = projectDao.makePersistent(project);
	}
	
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false)
	public boolean delete(Project project, MessageContext messageContext){
		if(project.getCategories().isEmpty()){
			project.getGroup().removeProject(project);
			projectDao.makeTransient(project);
			return true;
		}else{
			messageContext.addMessage((new MessageBuilder()).error().code("error_project_delete").build());
			return false;
		}
	}
	
	@Transactional(readOnly=true)
	public Project setup(String username){
		Project p = new Project();
		Member user = memberService.findByUsername(username);
		p.setGroup(user.getGroup());
		//TODO: authorities
		return p;
	}
	
	
	
	/********************************* DAO's *********************************/
	
	private ProjectDAO projectDao;
	
	public void setProjectDao(ProjectDAO projectDao) {
		this.projectDao = projectDao;
	}
	
	
	/******************************* Service's *******************************/
	
	private MemberService memberService;

	public void setMemberService(MemberService memberService) {
		this.memberService = memberService;
	}


	/******************************* Validation *******************************/
	
	private Validator validator;
	
	public boolean validate(Project project, MessageContext context){
		boolean valid = validator.validate(project, context);
		
		if(project.getName() != null && !project.getName().equals("")){
			Project projectWithName = null;
			try{
				projectWithName = projectDao.findByGroupAndName(project.getGroup(), project.getName());
			}catch(NoResultException e){
				//The project name isn't registered yet, so we just do nothing
			}
	
			if((projectWithName != null) && ((project.getId() == 0) || (projectWithName.getId() != project.getId()))){
				context.addMessage((new MessageBuilder()).error().code("error_existing_projectname").build());
				valid = false;
			}
		}
			
		return valid;
	}

	public void setValidator(Validator validator) {
		this.validator = validator;
	}
	
}
